# 移动,位置相关

def goto(length, x, y):
    # '''利用边界传送特性来移动'''
    cx,cy = get_pos_x(),get_pos_y()
    
    dx = x - cx
    dy = y - cy
    
    if dx != 0:
        if dx > 0:
            if dx > length - dx:
                dx = dx - length
                x_dir = West
            else:
                x_dir = East
        else:
            if -dx > length + dx:
                dx = length + dx
                x_dir = East
            else:
                x_dir = West
        for _ in range(abs(dx)):
            move(x_dir)
    
    if dy != 0:
        if dy > 0:
            if dy > length - dy:
                dy = dy - length
                y_dir = South
            else:
                y_dir = North
        else:
            if -dy > length + dy:
                dy = length + dy
                y_dir = North
            else:
                y_dir = South
        for _ in range(abs(dy)):
            move(y_dir)

def calc_pos_by_tile_number(length, tile_number):
    # '''地皮编号 计算 二维坐标'''
    return tile_number // length, tile_number % length

def calc_tile_number_by_pos(length, x, y):
    # '''二维坐标 计算 地皮编号'''
    return x * length + y

def get_pos():
    # '''获取当前位置,返回二元组'''
    return (get_pos_x(),get_pos_y())

def get_opposite_dir(dir):
    # '''获取方向的相反方向'''
    if dir == North:
        return South
    elif dir == South:
        return North
    elif dir == East:
        return West
    else:
        return East

def snake_traverse(length, x0, y0, x1, y1, action):
    # '''蛇形遍历 从给定的初始位置开始'''
    goto(length, x0, y0)
    for x in range(x0, x1 + 1):
        if (x - x0) % 2 == 0:
            # 从下到上
            for y in range(y0, y1 + 1):
                action(x, y)
                if y < y1:
                    move(North)
        else:
            # 从上到下
            for y in range(y1, y0 - 1, -1):
                action(x,y)
                if y > y0:
                    move(South)
        if x < x1:
            move(East)

def snake_traverse_from_cur(length, x0, y0, x1, y1, action):
    # '''蛇形遍历 从当前位置 只有固定世界大小时用'''
    for x in range(x0, x1 + 1):
        if (x - x0) % 2 == 0:
            # 从下到上
            for y in range(y0, y1 + 1):
                action(x, y)
                if y < y1:
                    move(North)
        else:
            # 从上到下
            for y in range(y1, y0 - 1, -1):
                action(x, y)
                if y > y0:
                    move(South)
        if x < x1:
            move(East)

# 多无人机

def create_task(fn, args):
    # '''
    # 为无人机创建一个任务, fn 为 任务函数, args 为任务参数
    # !注意此处不支持写不定参数
    # '''
    def _task():
        fn(args)
    return _task

# 便捷功能

def till_all():
    # '''
    # 耕地
    # 如果你的地大,无人机数量又少,那不如边耕地边种,这个适合后面无人机多了用的
    # '''
    ws = get_world_size()
    drone_num = min(ws,max_drones())
    def _till(t):
        goto(ws,t[0],t[1])
        moveuptimes = ws // drone_num - 1
        if ws % drone_num > 0:
            moveuptimes += 1
        for _ in range(ws):
                if get_ground_type() != Grounds.Soil:
                    till()
                move(East)
        while moveuptimes > 0:
            for _ in range(drone_num):
                move(North)
            for _ in range(ws):
                if get_ground_type() != Grounds.Soil:
                    till()
                move(East)
            moveuptimes -= 1
    if drone_num > 1:
        for i in range(1,drone_num):
            spawn_drone(create_task(_till,(0,i)))
    _till((0,0))
    
def pourwater(p=.75):
    # '''浇水, 若地皮含水量不足p值,则浇到p为止'''
    while num_items(Items.Water) > 5 and get_water() < p:
        use_item(Items.Water)
        
def gen_maze_fullsize():
    plant(Entities.Bush)
    substance = get_world_size() * 2**(num_unlocked(Unlocks.Mazes) - 1)
    use_item(Items.Weird_Substance, substance)
    return substance